home *** CD-ROM | disk | FTP | other *** search
/ AI Game Programming Wisdom / AIGameProgrammingWisdom.iso / SourceCode / 06 General Architectures / 06 Rabin / statemch.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-12-10  |  2.4 KB  |  111 lines

  1. /* Copyright (C) Steve Rabin, 2001. 
  2.  * All rights reserved worldwide.
  3.  *
  4.  * This software is provided "as is" without express or implied
  5.  * warranties. You may freely copy and compile this source into
  6.  * applications you distribute provided that the copyright text
  7.  * below is included in the resulting source code, for example:
  8.  * "Portions Copyright (C) Steve Rabin, 2001"
  9.  */
  10.  
  11. #include "statemch.h"
  12. #include "msgroute.h"
  13. #include "global.h"
  14.  
  15.  
  16. StateMachine::StateMachine( GameObject * object )
  17. {
  18.     m_Owner = object;
  19.     m_currentState = 0;
  20.     m_stateChange = false;
  21.     m_nextState = false;
  22.     m_timeOnEnter = 0.0f;
  23.     m_ccMessagesToGameObject = 0;
  24. }
  25.  
  26.     
  27. void StateMachine::Initialize( void )
  28. {
  29.     Process( EVENT_Enter, 0 );
  30. }
  31.  
  32.  
  33. void StateMachine::Update( void )
  34. {
  35.     Process( EVENT_Update, 0 );
  36. }
  37.  
  38.  
  39. void StateMachine::Process( StateMachineEvent event, MSG_Object * msg )
  40. {
  41.     
  42.     if( event == EVENT_Message && msg && GetCCReceiver() > 0 )
  43.     {    // CC this message
  44.         SendMsg( msg->GetMsgName(), GetCCReceiver() );
  45.     }
  46.  
  47.     if( States( event, msg, m_currentState ) == false )
  48.     {    // Current state didn't handle msg, try Global state (-1)
  49.         States( event, msg, -1 );
  50.     }
  51.  
  52.     // Check for a state change
  53.     int safetyCount = 50;
  54.     while( m_stateChange && (--safetyCount >= 0) )
  55.     {
  56.         assert( safetyCount > 0 && "StateMachine::Process - States are flip-flopping in an infinite loop." );
  57.  
  58.         m_stateChange = false;
  59.  
  60.         // Let the last state clean-up
  61.         States( EVENT_Exit, 0, m_currentState );
  62.  
  63.         // Set the new state
  64.         m_currentState = m_nextState;
  65.  
  66.         // Remember the time we entered this state
  67.         m_timeOnEnter = g_time.GetCurTime();
  68.  
  69.         // Let the new state initialize
  70.         States( EVENT_Enter, 0, m_currentState );
  71.     }
  72.  
  73. }
  74.  
  75.  
  76. void StateMachine::SetState( unsigned int newState )
  77. {
  78.     m_stateChange = true;
  79.     m_nextState = newState;
  80.  
  81. }
  82.  
  83.  
  84. void StateMachine::SendMsg( MSG_Name name, objectID receiver )
  85. {
  86.     g_msgroute.SendMsg( 0, name, receiver, m_Owner->GetID(), -1 );
  87.  
  88. }
  89.  
  90.  
  91. void StateMachine::SendDelayedMsg( float delay, MSG_Name name, objectID receiver )
  92. {
  93.     g_msgroute.SendMsg( delay, name, receiver, m_Owner->GetID(), -1 );
  94.     
  95. }
  96.  
  97.  
  98. void StateMachine::SendDelayedMsgToMe( float delay, MSG_Name name, MSG_Scope scope )
  99. {
  100.     if( scope == SCOPE_TO_THIS_STATE ) {
  101.         g_msgroute.SendMsg( delay, name, m_Owner->GetID(), m_Owner->GetID(), m_currentState );
  102.     }
  103.     else {
  104.         g_msgroute.SendMsg( delay, name, m_Owner->GetID(), m_Owner->GetID(), -1 );
  105.     }
  106.  
  107. }
  108.  
  109.  
  110.  
  111.